Flutter 2.8 | 一文解读重点更新
作者 / Chris Sells, Flutter 开发者体验产品经理
又到了北半球每年的这个时节: 树叶变黄、气温下降,而今年的最终稳定版本也在此时发布: Flutter 2.8 闪亮登场!这个版本凝聚了 207 位贡献者和 178 位审阅者的辛勤付出,合并了 2,424 个 PR,并解决了 2,976 个问题。在这里,我们要特别感谢此版本的杰出社区贡献者 Bartosz Selwesiuk,作为 Very Good Ventures 的 Flutter 工程师,他提供了 23 个 PR,其中大部分主要 "专注于" (原文如此) 面向 Web 的摄像头插件。
所有人的通力合作给引擎和 Flutter DevTools 带来了显著的性能改进、稳定的 Google Mobile Ads SDK for Flutter 版本、一系列全新的 Firebase 功能和改进、WebView 3.0、一批新的 Flutter Favorite package、朝着稳定版桌面端支持更进一步的大量更新,以及支持更多 package (包括 Firebase) 的新版本 DartPad。这应该是今年发布的最后一个版本,相信不负大家的期待。我们一起走进 Flutter 2.8!
性能
一如往常,Flutter 的第一要务是质量。我们的绝大部分工作旨在确保 Flutter 在其支持的设备上尽可能顺畅和稳健地运行。
此版本对应用启动延迟进行了改进。我们通过 Google Pay 对这些改进进行了测试。作为一个热门的大型应用,Google Pay 拥有超过 100 万行代码,可以确保这些改进能够在现实环境中产生显著的积极影响。所有相关改进使 Google Pay 在低端 Android 设备上运行时的启动延迟降低了 50%,在高端设备上降低了 10%。
对于 Flutter 影响 Dart VM 垃圾回收策略机制的改进,现在有助于避免在应用启动序列中出现错误的垃圾回收 (GC) 周期。例如,在 Android 上渲染第一帧之前,Flutter 现在只通知 Dart VM "TRIM_LEVEL_RUNNING_CRITICAL" 及以上的内存压力。在本地测试中,此改进将低端设备上的第一帧时间减少了多达 300 毫秒。
#90551: 只通知 Dart VM "TRIM_LEVEL_RUNNING_CRITICAL" 及以上的内存压力 https://github.com/flutter/flutter/issues/90551
#29145: 在 UI/Raster 线程上不要对 Shell::OnCreatePlatformView 进行序列化操作 https://github.com/flutter/engine/pull/29145#pullrequestreview-778935616 #91711: UI 线程上的 Shell::OnPlatformViewCreated 不应进行序列化 https://github.com/flutter/flutter/issues/91711
#29291: 延迟默认字体管理器,使其与 Isolate 设置同时运行
https://github.com/flutter/engine/pull/29291
#91382: 引擎不应使用应用快照加载 VM 服务 https://github.com/flutter/flutter/issues/91382 #29245: 构建一个用于在 Android 分析模式启动 Service Isolate 的专用快照 https://github.com/flutter/engine/pull/29245 #92120: 为提供给 Dart VM 的类型映射提供提示 https://github.com/flutter/flutter/issues/92120
#28903: 如在应用启动时启用 systrace,则使用 systrace 记录器,并在 Android 发布模式下启用 systrace https://github.com/flutter/engine/pull/28903
此外,为了创建卡顿更少的动画,一些开发者希望性能跟踪记录中包含更多关于光栅缓存行为的信息,这使得 Flutter 能够对昂贵和重复使用的图片进行图块搬移,无需在每一帧上重新进行绘制。性能跟踪记录中的新流程事件现在允许开发者跟踪光栅缓存图片的生命周期。
#92286: 为光栅缓存的生成至删除事件添加流程或异步事件 https://github.com/flutter/flutter/issues/92286
#3451: 在性能页面增加跟踪绘制和跟踪布局开关 https://github.com/flutter/devtools/pull/3451
启用任一跟踪功能时,时间轴将根据选项相应地包含新的 "已构建 widget"、"已布局渲染对象" 和 "已绘制渲染对象" 事件。
另外,此版本的 DevTools 添加了新功能来分析应用启动时的性能表现。此剖析文件包含从 Dart VM 初始化到第一个 Flutter 帧渲染完成的所有 CPU 采样。在点击 "剖析应用启动 (Profile app starup)" 按钮并加载应用启动剖析文件后,您将看到剖析文件的 "AppStartUp" 用户标签已被选中。您还可以通过在列表中选择这个用户标签过滤器 (如果可用),来加载应用启动剖析文件。选择此标签会显示您应用启动的剖析数据。
#3357: 增加应用启动剖析功能,以及改进 CPU 剖析缓存 https://github.com/flutter/devtools/pull/3357
HtmlElementView https://api.flutter.cn/flutter/widgets/HtmlElementView-class.html 在 Web 中展示图片 https://flutter.cn/docs/development/platform-integration/web-images#use-img-in-a-platform-view
在 Flutter 之前的版本中,嵌入平台视图会立即构建一个新的 canvas,每增加一个平台视图,都会添加一个新的 canvas。这些额外生成的 canvas 成本高昂,因为每个 canvas 都是整个窗口的大小。而在新版本中,我们复用了为之前的平台视图创建的 canvas,因此相比较之前每秒承担 60 倍的成本,如今在整个应用的生命周期内只需要承担一次成本即可。这意味着您可以在 Web 应用中创建多个 HtmlElementView 而不损失性能,同时可减少使用平台视图时的滚动卡顿。
#28087: 优化特殊用例下的 CanvasKit 平台视图 https://github.com/flutter/engine/pull/28087
生态系统
Flutter 不仅仅是框架、引擎和工具: pub.dev 上有超过 20,000 个与 Flutter 兼容的 package 和插件,而且每天还在不断产生更多的内容。Flutter 开发者日常大量互动的内容构成了一个更为庞大的生态系统,让我们一起来看看自上个版本以来 Flutter 生态系统的发展吧。
首先,也是最重要的是,Google Mobile Ads SDK for Flutter 已正式发布。
此版本支持 5 种广告格式,集成了 AdMob 和 Ad Manager 支持,并包含新中介功能的测试版,可帮助您优化广告效果。有关将 Google Ads 集成到 Flutter 应用以及其他获利方案的更多信息,请查看有关获利的详细信息:
https://flutter.cn/monetization
WebView 3.0
这次 Flutter 还带来了 webview_flutter 插件的 3.0 版本:
支持使用 POST 和 GET 填充内容 (#4450、#4479、#4480、#4573)
https://github.com/flutter/plugins/pull/4450 https://github.com/flutter/plugins/pull/4479 https://github.com/flutter/plugins/pull/4480 https://github.com/flutter/plugins/pull/4573
从文件和字符串加载 HTML (#4446、#4486、#4544、#4558)
https://github.com/flutter/plugins/pull/4446 https://github.com/flutter/plugins/pull/4486 https://github.com/flutter/plugins/pull/4544 https://github.com/flutter/plugins/pull/4558
透明背景支持 (#3431、#4569、#4570)
https://github.com/flutter/plugins/pull/3431 https://github.com/flutter/plugins/pull/4569 https://github.com/flutter/plugins/pull/4570
在加载内容前写入 Cookie (#4555、#4556、#4557)
https://github.com/flutter/plugins/pull/4555 https://github.com/flutter/plugins/pull/4556 https://github.com/flutter/plugins/pull/4557
而且在 3.0 版本中,webview_flutter 还新增了对 Web 平台的初步支持。有许多人希望能在 Flutter Web 应用中托管 WebView,这可让他们通过单个源代码库来构建移动或 Web 应用。那如何在 Flutter Web 应用中托管 WebView 呢?代码如下:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_web/webview_flutter_web.dart';
void main() {
runApp(const MaterialApp(home: HomePage()));
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
void initState() {
super.initState();
// required while web support is in preview
if (kIsWeb) WebView.platform = WebWebViewPlatform();
}
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Flutter WebView example')),
body: const WebView(initialUrl: 'https://flutter.dev'),
);
}
它在 Web 上运行时的效果也正如您预期的那样:
注意,当前 Web 端 webview_flutter 的实现有许多限制,因为它是借助 iframe 构建的,而 iframe 只能支持简单的网址加载,无法控制加载的内容或与其交互 (更多详细信息见 webview_flutter_web README)。但是,应大家需求,我们将提供 webview_flutter_web,作为未整合的插件供大家使用。如果您想一试,请将以下代码行添加到您的 pubspec.yaml 中:
dependencies:
webview_flutter: ^3.0.0
webview_flutter_web: ^0.1.0 # add unendorsed plugin explicitly
Webview_flutter_web README https://pub.flutter-io.cn/packages/webview_flutter_web 未整合的联合插件 https://flutter.cn/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
如果您对 webview_flutter v3.0 有任何反馈,无论是否基于 Web 端,请将其作为 WebView 问题提交至 Flutter repo。此外,如果您之前没有使用过 WebView 或想回顾一下其用法,请查看全新的 WebView Codelab,它会向您逐步介绍在 Flutter 应用中托管 Web 内容的过程。
提交问题 https://github.com/flutter/flutter/issues WebView Codelab https://codelabs.developers.google.com/codelabs/flutter-webview
https://flutter.cn/docs/development/packages-and-plugins/favorites#flutter-ecosystem--committee
新 Router API 的三个自定义路由 package: beamer、routemaster 和 go_router
https://pub.flutter-io.cn/packages/beamer https://pub.flutter-io.cn/packages/routemaster https://pub.flutter-io.cn/packages/go_router
drift,重命名自 Flutter 和 Dart 中的一个已经可用且颇为流行的反应式持久性库,它建立于 sqlite 之上:
https://pub.flutter-io.cn/packages/drift https://pub.flutter-io.cn/packages/sqlite3
freezed 是一个 Dart 的 "语言补丁",为定义模型、克隆对象、模式匹配等提供简单的语法
https://pub.flutter-io.cn/packages/freezed
dart_code_metrics
https://pub.flutter-io.cn/packages/dart_code_metrics
此外还有几个好用的图形用户界面 package: flex_color_scheme、flutter_svg、feedback、toggle_switch 和 auto_size_text
https://pub.flutter-io.cn/packages/flex_color_scheme
https://pub.flutter-io.cn/packages/flutter_svg
https://pub.flutter-io.cn/packages/feedback
https://pub.flutter-io.cn/packages/toggle_switch
https://pub.flutter-io.cn/packages/auto_size_text
祝贺这些 package 的作者,感谢您用自己的辛勤努力支持 Flutter 社区。如果您想要提名最喜欢的 Flutter package 来获得 Flutter Favorite 奖项,请遵循 Flutter Favorite 计划页面上的指南和说明:
https://flutter.cn/docs/development/packages-and-plugins/favorites
https://flutter.cn/docs/development/packages-and-plugins/developing-packages#plugin-platforms
flutter:
plugin:
platforms:
android:
package: com.example.hello
pluginClass: HelloPlugin
ios:
pluginClass: HelloPlugin
然而,随着 Dart FFI 越来越成熟,您也有可能完全在 Dart 中实现特定平台的功能,就像 path_provider_windows package 那样。在这种情况下,没有任何原生类可以使用,但您仍然需要指定 package 只支持某些平台,您可以使用 dartPluginClass 属性代替:
flutter:
plugin:
implements: hello
platforms:
windows:
dartPluginClass: HelloPluginWindows
Dart FFI https://dart.dev/guides/libraries/c-interop path_provider_windows https://pub.flutter-io.cn/packages/path_provider_windows
有了这个设置,在没有任何原生代码的情况下,您也可以把 package 设置成只支持某些特定平台。您还必须提供 Dart 插件类,您可以通过仅 Dart 的平台实现官方文档中了解详情:
https://flutter.cn/docs/development/packages-and-plugins/developing-packages#dart-only-platform-implementations
所有 FlutterFire 插件已从 Beta 版过渡到稳定版 Dartpad 中增加了对若干 Firebase 服务的支持 用于更轻松构建身份验证和实时 Firestore 查询界面的库 针对 Flutter 的新 Firestore 对象/文档映射 (Alpha 版)
http://firebase.flutter.dev/
Analytics https://firebase.flutter.dev/docs/analytics/overview Dynamic Links https://firebase.flutter.dev/docs/dynamic-links/overview In-App Messaging https://firebase.flutter.dev/docs/in-app-messaging/overview/ Performance Monitoring https://firebase.flutter.dev/docs/performance/overview Realtime Database https://firebase.flutter.dev/docs/database/overview Remote Config https://firebase.flutter.dev/docs/remote-config/overview Installations https://firebase.flutter.dev/docs/installations/overview
https://github.com/FirebaseExtended/flutterfire/pull/6549
import 'package:firebase_core/firebase_core.dart';
import 'firebase_options.dart'; // generated via `flutterfire` CLI
Future<void> main() async {
// initialize firebase across all supported platforms
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
上面的代码使用适合每个受支持平台的选项初始化 Firebase 应用,这些选项在 firebase_options.dart 文件中定义,该文件包含每个平台的数据结构,如下所示:
static const FirebaseOptions web = FirebaseOptions(
apiKey: 'AIzaSyCZFKryCEiKhD0JMPeq_weJguspf09h7Cg',
appId: '1:111079797892:web:b9195888086158195ffed1',
messagingSenderId: '111079797892',
projectId: 'flutterfire-fun',
authDomain: 'flutterfire-fun.firebaseapp.com',
storageBucket: 'flutterfire-fun.appspot.com',
measurementId: 'G-K029Y6KJDX',
);
要收集每个平台初始化选项数据结构的数据,请使用新的 flutterfire CLI 工具:
https://pub.flutter-io.cn/packages/flutterfire_cli
此工具会深入挖掘平台特定子文件夹中的数据,以找到唯一的软件包 ID,然后用它来查找匹配平台特定应用的 Firebase 项目特定详细信息,如果没有查找到的话,甚至还会创建一个新的 Firebase 项目和/或新的平台特定应用。这意味着,您不再需要下载 json 文件并将其添加到 Android 项目、或下载 plist 文件并将其添加到 iOS 和 macOS 项目,或将代码粘贴到您 Web 项目的 index.html 中: 无论您的 Firebase 项目支持哪个平台,这段 Dart 代码都将为您的应用完成 Firebase 的初始化。请注意,要让 FlutterFire 应用正常工作,需要的初始化工作可能不止于此,例如,您可能需要将 Crashlytics 符号的创建集成到您的 Android 构建或 iOS 构建中,但在一个新的 Firebase 项目中,这些操作应该只需要几分钟就可以完成并顺利运行。
#7359: 自动注入 Firebase JS SDK https://github.com/FirebaseExtended/flutterfire/pull/7359 将 Crashlytics 插件添加至应用 https://firebase.google.com/docs/crashlytics/get-started?platform=android#add-plugin 设置 Xcode 以自动上传 dSYM 文件 https://firebase.google.com/docs/crashlytics/get-started?platform=ios#set-up-dsym-uploading
Dart 聊天应用示例 https://dartpad.dev/?id=d57c6c898dabb8c6fb41018588b8cf73 原作者动态 https://twitter.com/puf/status/1458516522133909506
DartPad 的 FlutterFire 支持还包含在文档中直接嵌入 DartPad 实例的功能:
https://firebase.flutter.dev/docs/firestore/example/
在上面的示例中,您可以看到 Cloud Firestore 的文档和示例应用的代码,您可以直接在浏览器中运行和编辑这些代码,而无需安装内容、创建测试项目,甚至不需要复制/粘贴代码。代码已经在页面中就绪,可以立即使用。
示例应用 https://github.com/FirebaseExtended/flutterfire/tree/master/packages/cloud_firestore/cloud_firestore/example
flutterfire_ui https://pub.flutter-io.cn/packages/flutterfire_ui
有了这个配置,您就可以使用如下代码触发身份验证流程:
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutterfire_ui/auth.dart';
import 'firebase_options.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => MaterialApp(
home: AuthenticationGate(),
);
}
class AuthenticationGate extends StatelessWidget {
const AuthenticationGate({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) => StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// User is not signed in - show a sign-in screen
if (!snapshot.hasData) {
return SignInScreen(
providerConfigs: [
EmailProviderConfiguration(),
GoogleProviderConfiguration(
clientId: 'xxxx-xxxx.apps.googleusercontent.com',
),
],
);
}
return HomePage(); // show your app’s home page after login
},
);
}
在这段代码中,我们初始化了 Firebase,由于用户尚未登录,因此显示登录屏幕。SigninScreen widget 配置了电子邮件登录和 Google 身份验证登录。我们还使用 firebase_auth package 监听用户的身份验证状态,一旦他们完成登录,我们就可以显示应用的其余部分。使用上面这段代码,您就可以为所有支持 Firebase 的平台 (Android、iOS、Web 和 macOS) 提供可用的登录流程。
只需增加一些配置,即可轻松添加图像和自定义文本 (详细信息见文档),从而构建出功能齐备的登录体验:
https://firebase.flutter.dev/docs/ui/overview
上面是移动版本的截图,但由于 flutterfire_ui 屏幕是响应式的,以下即为桌面设备上的界面:
如果用户已经使用电子邮件/密码注册过账号,那他们可以立即登录。如果他们使用 Google 身份验证,无论是在移动设备、Web 还是桌面设备上,系统都会显示常规的 Google 身份验证流程。如果他们还没有帐号,可以按下登录屏幕上的按钮并转到注册屏幕。在他们登录或注册后,会有以下流程可用: 验证电子邮件地址、重置密码、登出和关联社交身份验证帐号。所有平台都适用电子邮件登录,并支持 Google、Facebook 和 Twitter 的社交身份验证,部分支持 Apple (因为它不适用于 Android)。flutterfire_ui 中的身份验证支持多种场景和导航方案,以及自定义和本地化选项。您可以在官方文档中参阅详细文档和示例:
https://firebase.flutter.dev/docs/ui/overview
并且,身份验证不是 flutterfire_ui 支持的唯一 Firebase 界面相关功能。在向用户展示来自 Firebase 查询的实时、无限滚动的数据列表时,此版本提供 FirestoreListView,您可以使用它在应用中呈现实时查询的结果,如下所示:
class UserListView extends StatelessWidget {
UserListView({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Contacts')),
body: FirestoreListView<Map>(
query: usersCollection,
pageSize: 15,
primary: true,
padding: const EdgeInsets.all(8),
itemBuilder: (context, snapshot) {
final user = snapshot.data();
return Column(
children: [
Row(
children: [
CircleAvatar(
child: Text((user['firstName'] ?? 'Unknown')[0]),
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'${user['firstName'] ?? 'unknown'} '
'${user['lastName'] ?? 'unknown'}',
style: Theme.of(context).textTheme.subtitle1,
),
Text(
user['number'] ?? 'unknown',
style: Theme.of(context).textTheme.caption,
),
],
),
],
),
const Divider(),
],
);
},
),
);
}
实际运行效果如下:
或者,如果您想为用户提供在表格中创建、读取、更新和删除条目的功能,可以使用 FirestoreDataTable:
class FirestoreTableStory extends StatelessWidget {
FirestoreTableStory({Key? key}) : super(key: key);
// live Firestore query
final usersCollection = FirebaseFirestore.instance.collection('users');
@override
Widget build(BuildContext context) {
return FirestoreDataTable(
query: usersCollection,
columnLabels: const {
'firstName': Text('First name'),
'lastName': Text('Last name'),
'prefix': Text('Prefix'),
'userName': Text('User name'),
'email': Text('Email'),
'number': Text('Phone number'),
'streetName': Text('Street name'),
'city': Text('City'),
'zipCode': Text('Zip code'),
'country': Text('Country'),
},
);
}
}
有关身份验证、列表视图和数据表的详细信息,请查看 flutterfire_ui 文档。由于这是一个预览版,我们计划添加更多功能。如果您有问题或功能需求,请前往 GitHub repo 的讨论专区提交或提出问题。
flutterfire_ui 文档 https://firebase.flutter.dev/docs/ui/overview/ GitHub repo https://github.com/FirebaseExtended/flutterfire/discussions/6978
@JsonSerializable()
class Person {
Person({required this.name, required this.age});
final String name;
final int age;
}
@Collection<Person>(‘/persons’)
final personsRef = PersonCollectionReference();
Firestore ODM
https://firebase.flutter.dev/docs/firestore-odm/overview/
这些类型就位后,您就可以执行类型安全查询:
personsRef.whereName(isEqualTo: 'Bob');
personsRef.whereAge(isGreaterThan: 42);
Firestore ODM 文档 https://firebase.flutter.dev/docs/firestore-odm/overview/ Firestore ODM 会话 https://github.com/FirebaseExtended/flutterfire/discussions/7475
桌面端
Flutter 2.8 版本朝着桌面端 (Windows、macOS 和 Linux) 的稳定支持又前进了一大步。我们对质量的要求很高,包括国际化和本地化支持,例如我们新增的中文、韩文以及日文汉字 IME 支持。或者又比如我们正在构建的对 Windows 无障碍支持的紧密整合。仅仅让稳定渠道的 Flutter 在桌面设备上运行是不够的 (即便它已经能在带标识的 beta 渠道运行了),它还必须针对世界各地的语言和文化以及不同能力的用户提供良好的运行状态。Flutter 桌面端支持在质量方面尚未达到预期的水平,但我们正在向这个目标迈进!
#29620: 中文 IME 支持 https://github.com/flutter/engine/pull/29620 #24713: 韩文 IME 支持 https://github.com/flutter/engine/pull/24713 #29761: 日文汉字 IME 支持 https://github.com/flutter/engine/pull/29761 #77838: Windows 无障碍支持 https://github.com/flutter/flutter/issues/77838 Stable 渠道包含了一份 Beta 渠道的桌面支持 https://flutter.cn/docs/desktop#beta-snapshot-in-stable-channel
为了让桌面端支持进入稳定版本,我们做了许多工作,其中包括完全重新构建 Flutter 处理键盘事件的架构,以实现同步响应。如此一来就可以用 widget 来处理按键,并取消其在树的其他部分的传递。这方面的成果首先出现在 Flutter 2.5 中,并在 Flutter 2.8 中修复了一些问题和回归,实现了稳定的质量。除此之外,我们还在重新设计特定设备的键盘输入处理方式,以及重构 Flutter 处理文本编辑的方式,所有这些对于键盘输入密集型的桌面应用都很有必要。
处理同步键盘事件
https://docs.google.com/document/d/1rWXSjkb2ZKv-cpg26lVK0aZi4cVeXJ8j7YmSJdq2TOM/edit#heading=h.pub7jnop54q0
#33521: 需要一个从嵌入器发送同步键盘事件至 Dart 并获得响应的方法
https://github.com/flutter/flutter/issues/33521
#44918: 特定设备的键盘事件应该在嵌入器中发生
https://github.com/flutter/flutter/issues/44918
#86736: 文本编辑模型重构
https://github.com/flutter/flutter/pull/86736
此外,我们还持续扩展了 Flutter 的视觉密度支持,并开放对话框的对齐方式,这都是为了实现更适用于桌面设备的界面。
#89353: 增加 visualDensity、focusNode 和 enableFeedback https://github.com/flutter/flutter/pull/89353 #88984: 允许对话框进行自定义对齐 https://github.com/flutter/flutter/pull/88984
最后,Flutter 团队并不是唯一致力于 Flutter 桌面端支持的团队。举个例子,Canonical 的桌面团队正在与 Invertase 合作,致力在 Linux 和 Windows 上实现最流行的 Flutter Firebase 插件。
您可以在 Invertase 博客中进一步了解其预览版:
https://invertase.io/blog/announcing-flutterfire-desktop
DartPad
完整的 Flutter 版本发布必然涉及工具方面的改进。在此版本中,DartPad 最大的改进是对更多 package 的支持。事实上,现在支持导入的 package 达到了 23 个。除了对几个 Firebase 服务的支持外,还支持 bloc、characters、collection、google_fonts 和 flutter_riverpod 等流行的 package。DartPad 团队将继续增加新的 package,如果您想查看目前支持哪些 package,可以点击下方截图右下角的信息图标:
如果您想要了解 DartPad 支持新 package 的计划,请查看 Dart wiki 上的这篇文章:
DartPad 还有一个相当实用的新特性。此前,DartPad 一直运行最新的稳定版本。在这个版本中,您可以让 DartPad 使用最新的 beta 版或上一个稳定版本 (称为 "旧渠道"),只需使用状态栏中新增的渠道 (Channel) 菜单切换即可。
移除 dev 渠道
Flutter 的 "渠道 (channel)" 控制着底层 Flutter 框架和引擎在您开发机器上变化的速度,稳定 (stable) 渠道表示最少的流失,而主 (master) 渠道则相反。由于资源限制,我们最近停止了 dev 渠道的更新。虽然我们确实收到了与此相关的一些问题,但我们发现只有不到 3% 的 Flutter 开发者使用该渠道。因此我们决定正式停用 dev 渠道。虽然很少有开发者使用 dev 渠道,但 Flutter 工程师需要花费大量时间和精力来维护它。如果您所有的时间都在使用稳定渠道 (正如 90% 以上的 Flutter 开发者所做的那样),那您根本不会再需要 dev 渠道。放弃这个渠道意味着您可以少做一个决定,而 Flutter 团队可以将时间和精力放在其他事情上。
稳定 (stable) 渠道代表着我们构建的最高质量。此渠道一般每季度发布一次,期间会对关键问题进行热修复。这是 "慢" 渠道: 安全、成熟、提供长期支持。 Beta 渠道为喜欢更快节奏的开发者们提供了一种替代 stable 渠道的快速迭代方案。目前每月发布,在发布前稳定。这是 "快" 渠道。如果我们发现 dev 渠道能满足 beta 渠道目前无法满足的需求,我们可能会改变对 beta 渠道的处理方案来满足这些需求 (例如加快 beta 渠道的发布节奏,以及降低其测试和热修复级别)。 主 (master) 渠道是活跃的开发渠道。我们对此渠道不提供支持,但我们会针对它进行全面的单元测试。能适应不稳定版本的贡献者或高级用户可以使用该渠道。在这个渠道中,我们会快速构建和破坏一些功能 (然后很快将其修复)。
在未来几个月停用 dev 渠道的过程中,请您考虑使用 beta 或主 (master) 渠道,具体取决于您对流失的容忍度,以及您对更新和质量的要求。
重大变更
像往常一样,我们会尽力减少每个版本中重大变更的数量。在 Flutter 2.8 中,除了已经过期并根据我们的重大变更政策移除的已弃用 API 之外,没有其他重大变更:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
#90292: 移除被弃用的 autovalidate
https://github.com/flutter/flutter/pull/90292
#90293: 移除被弃用的 FloatingHeaderSnapConfiguration.vsync
https://github.com/flutter/flutter/pull/90293
#90294: 移除被弃用的 AndroidViewController.id
https://github.com/flutter/flutter/pull/90294
http://androidviewcontroller.id/
#90295: 移除被弃用的 BottomNavigationBarItem.title
https://github.com/flutter/flutter/pull/90295
#90296: 移除已弃用的文本输入格式类
https://github.com/flutter/flutter/pull/90296
如果您仍在使用这些 API,并且想要详细了解如何更新您的代码,可以阅读迁移指南。非常感谢社区一如既往地提供测试,帮助我们识别以上重大变更。
迁移指南: 2.5 版本之后弃用的 API https://flutter.cn/docs/release/breaking-changes/2-5-deprecations 提供测试 https://github.com/flutter/tests/blob/master/README.md
总结
在我们告别 2021 年并展望 2022 年之际,Flutter 团队要对整个 Flutter 社区的工作和支持表示感谢。诚然,我们正在为世界上越来越多的开发者构建 Flutter,但没有您我们就无法做到这一切。Flutter 社区是独一无二的,我们感谢您所做的一切。祝您假期愉快,我们新的一年见!
推荐阅读